/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.farent.solutions.plugins.stripes.hyperstripes.utils;

import com.farent.solutions.plugins.stripes.hyperstripes.core.ClassResolver;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Collections;
import java.util.List;
import java.util.regex.Pattern;

/**
 *
 * @author user
 */
public class ResourceUtil
{
    /**
     * Find resources in the specified folder on the classpath using the provided parameters
     * @param path the folder in which search is to be done
     * @param extension the file extension
     * @param pattern the pattern to use for filtering resources that match the extension provided
     * @return return a list of strings that define the path to the found resources in the classpath
     */
    public static List<String> find(String path, String extension, Pattern pattern) {
        ClassResolver<String> resolver = new ClassResolver<String>(extension, pattern);
        List<String> children = null;
        try {
            List<URL> urls = Collections.list(resolver.getClassLoader().getResources(path));
            for (URL url : urls) {
                children = resolver.listClassResources(url, path, extension);
            }
        } catch (IOException ioe) {
            throw new RuntimeException(ioe.toString());
        }

        return children;
    }

    /**
     * Find first resource in the specified folder on the classpath using the provided parameters
     * @param path the folder in which search is to be done
     * @param extension the file extension
     * @param pattern the pattern to use for filtering resources that match the extension provided
     * @return return a list of strings that define the path to the found resources in the classpath
     */
    public static InputStream findFirst(String path, String extension, Pattern pattern) {
        ClassResolver<String> resolver = new ClassResolver<String>(extension, pattern);
        InputStream is = null;
        try {
            List<URL> urls = Collections.list(resolver.getClassLoader().getResources(path));
            String found = resolver.listClassResources(urls.get(0), path, extension).get(0);
            if ( !Utils.nullOREmpty( found ) ) {
                is = Thread.currentThread().getContextClassLoader().getResourceAsStream(found);
            }
            return is;
        } catch (IOException ioe) {
            throw new RuntimeException(ioe.toString());
        }
    }

    /**
     * Find first resource in the specified folder on the classpath using the provided parameters
     * @param path the folder in which search is to be done
     * @param extension the file extension
     * @param pattern the pattern to use for filtering resources that match the extension provided
     * @return return a list of strings that define the path to the found resources in the classpath
     */
    public static String findFirstAsPath(String path, String extension, Pattern pattern) {
        ClassResolver<String> resolver = new ClassResolver<String>(extension, pattern);
        try {
            List<URL> urls = Collections.list(resolver.getClassLoader().getResources(path));
            return urls.get(0).toString();
//            return resolver.listClassResources(urls.get(0), path, extension).get(0);
        } catch (Exception ioe) {
            throw new RuntimeException(ioe.toString());
        }
    }

    /**
     * Find resources in the specified folder on the classpath using the provided parameters
     * @param path the folder in which search is to be done
     * @param fileName the fileName
     * @return return a list of strings that define the path to the found resources in the classpath
     */
    public static List<String> find(String path, String fileName) {
        Pattern pattern = Pattern.compile(fileName);
        String extension = ResourceUtil.getExtension(fileName);
        return find(path, extension, pattern);
    }

    /**
     * Find resources in the specified folder on the classpath using the provided parameters
     * @param path the folder in which search is to be done
     * @param extension the file extension
     * @param pattern the pattern to use for filtering resources that match the extension provideds
     * @return an InputStream to the first matching resource if any is found or null
     */
    public static InputStream getResource(String folder, String url, Pattern pattern) {
        InputStream is = null;
        List<String> urls = null;
        if( pattern != null)
            urls = ResourceUtil.find(folder, url, pattern);
        else
            urls = ResourceUtil.find(folder, url);
        if (urls != null && !urls.isEmpty()) {
            String found = urls.get(0);
            is = Thread.currentThread().getContextClassLoader().getResourceAsStream(found);
        }
        return is;
    }

    /**
     * Find resources in the specified folder on the classpath using the provided parameters
     * @param path the folder in which search is to be done
     * @param filename the file extension
     * @return an InputStream to the first matching resource if any is found or null
     */
    public static InputStream getResource(String folder, String filename) {
        return ResourceUtil.getResource(folder, filename, null);
    }

    
    /**
     * Get the file extension for the specified filename. eg hs.js returns .js
     * @param filename
     * @return
     */
    public static String getExtension(String filename) {
        int mid = filename.lastIndexOf(".");
        return filename.substring(mid, filename.length());
    }


    /**
     * Trims a file path to get only the path to the folder. eg "/js/hs.js" returns /js/
     * @param path the filepath to process
     * @return the path to the folder containing the file
     */
    public static String trimPathToFolders(String path) {
        String result = null;
        try {
            int lastSlashPos = path.lastIndexOf("/");
            result = path.substring(0, lastSlashPos+1);
        } catch (Exception e) {
            throw new RuntimeException(e.toString());
        }
        return result;
    }

    /**
     * Checks if the url matches an archive request
     * @param url
     * @return
     */
    public static boolean isArchiveUrl(String url) {
        for (int i = 0; i < ARCHIVE_EXTENSTIONS.length; i++) {
            String ext = ARCHIVE_EXTENSTIONS[i];
            if( url.contains(ext))
                return true;
        }
        return false;
    }

    /**
     * Get the archive filename eg lib/myzip.zip!/co/uk returns lib/myzip.zip
     * @param filename
     * @return
     */
    public static String getArchiveFileNameWithPath(String archivefilePath) {
        if( !isArchiveUrl( archivefilePath ) )
            throw  new RuntimeException("file does not have the right format! Must contain either .zip! or .jar!");
        String extType = getArchiveExtension(archivefilePath);
        String[] parts = getArchiveFileNameParts(archivefilePath);
        String firstPart = parts[0];
        return firstPart + extType.substring(0, extType.length() -1 );
    }

    /**
     * Get the archive filename eg lib/myzip.zip!/co/uk returns lib/myzip.zip
     * @param filename
     * @return
     */
    public static String[] getArchiveFileNameParts(String archivefilePath) {
        if( !isArchiveUrl( archivefilePath ) )
            throw  new RuntimeException("file does not have the right format! Must contain either .zip! or .jar!");
        String extType = getArchiveExtension(archivefilePath);
        Pattern p = Pattern.compile(extType);
        return p.split(archivefilePath, 2);
    }

    /**
     * Get the archive filename eg lib/myzip.zip!/co/uk returns myzip.zip
     * @param filename
     * @return
     */
    public static String getArchiveFileName(String archivefilePath) {
        String path = getArchiveFileNameWithPath(archivefilePath);
        int lastSlashPos = path.lastIndexOf("/");
        return path.substring( lastSlashPos + 1);
    }


    /**
     * Get the archive filename extension. eg myzip.zip! returns .zip!
     * @param filename
     * @return
     */
    public static String getArchiveExtension(String archivefilePath) {
        if( !isArchiveUrl( archivefilePath ) )
            throw  new RuntimeException("file does not have the right format! Must contain either .zip! or .jar!");

        for (int i = 0; i < ARCHIVE_EXTENSTIONS.length; i++) {
            String ext = ARCHIVE_EXTENSTIONS[i];
            if( archivefilePath.contains(ext) )
                return ext;
        }
        return null;
    }

    /**
     * Finds the specified reource within the specified InputStream
     * @param resourceFileName
     * @param stream
     * @return
     */
//    public static  InputStream getResourceFromJarStream(String resourceFileName,
//            ZipInputStream jar) throws IOException
//    {
//        // Include the leading and trailing slash when matching names
//        if ( !resourceFileName.startsWith ( "/" ) )
//        {
//            resourceFileName = "/" + resourceFileName;
//        }
//        if ( !resourceFileName.endsWith ( "/" ) )
//        {
//            resourceFileName = resourceFileName + "/";
//        }
//
//        // Iterate over the entries and collect those that begin with the requested path
//        List<String> resources = new ArrayList<String> ();
////        ZipInputStream zis = null;
//
//        for ( ZipEntry entry; ( entry = jar.getNextEntry() ) != null; )
//        {
//            if ( !entry.isDirectory () )
//            {
//                // Add leading slash if it's missing
//                String name = entry.getName ();
//                if ( !name.startsWith ( "/" ) )
//                {
//                    name = "/" + name;
//                }
//
//                // Check file name
//                if ( name.endsWith ( extension ) && name.startsWith ( path ) )
//                {
//                    jar.
//                    resources.add ( name.substring ( 1 ) ); // Trim leading slash
//                }
//            }
//        }
//        return resources;
//    }

    private static String[] ARCHIVE_EXTENSTIONS = {".jar!", ".zip!"};
}
